/**
 * ScannerCircle.java
 *
 * Roslan's Remake of MOO in 3D using Ardor3D
 * (C) 2011 Roslan Amir. All rights reserved.
 */

package com.roslan.games.moo3d.spatial;

import java.awt.Point;

import com.ardor3d.math.Vector3;
import com.ardor3d.math.type.ReadOnlyColorRGBA;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.scenegraph.Line;
import com.ardor3d.scenegraph.Node;
import com.roslan.games.moo3d.utils.HexGridUtils;

/**
 * This class represents the node for displaying the range of the scanners around a player colony.
 * 
 * @author Roslan Amir
 * @version 1.0 - Mar 4, 2011
 */
public class ScannerCircle extends Node {

	/**
	 * Constructor.
	 * 
	 * @param radius - the radius (in hex tiles) of the circle
	 * @param color - the color to use (the player's banner color)
	 */
	public ScannerCircle(int radius, ReadOnlyColorRGBA color) {
		super("ScannerCircleNode");

		/*
		 * Get the list of hex tiles that represent the perimeter of the circle. The return value is an array of Point objects.
		 */
		final Point[] tiles = HexGridUtils.getCircleHexes(radius);

		final Vector3[] vertices = new Vector3[((2 + radius * 4) * 6)]; // 6 is because a hexagon has 6 sides
		final double[][] tuples = new double[3][2];
		int verticesIndex = 0;
		int tilesIndex = 0;

		/*
		 * This section draws the single edge on the lower-right part of the circle
		 */
		final double[] origin = new double[2];
		HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
		HexGridUtils.getLowerRightSegmentVertices(tuples); // return array is [2][2]
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);

		/*
		 * This section draws the edges on the lower-left part of the circle
		 */
		HexGridUtils.getLowerLeftLeftSegmentVertices(tuples); // return array is [3][2]
		for (int i = 0; i < radius; i++) {
			HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[2][0], origin[1] + tuples[2][1], 0);
			tilesIndex++;
		}

		/*
		 * This section draws the single edge on the lower-left part of the circle
		 */
		HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
		HexGridUtils.getLowerLeftSegmentVertices(tuples); // return array is [2][2]
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);

		/*
		 * This section draws the edges on the upper-left part of the circle
		 */
		HexGridUtils.getLeftUpperLeftSegmentVertices(tuples); // return array is [3][2]
		for (int i = 0; i < radius; i++) {
			HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[2][0], origin[1] + tuples[2][1], 0);
			tilesIndex++;
		}

		/*
		 * This section draws the single edge on the left part of the circle
		 */
		HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
		HexGridUtils.getLeftSegmentVertices(tuples); // return array is [2][2]
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);

		/*
		 * This section draws the edges on the upper part of the circle
		 */
		HexGridUtils.getUpperLeftUpperRightSegmentVertices(tuples); // return array is [3][2]
		for (int i = 0; i < radius; i++) {
			HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[2][0], origin[1] + tuples[2][1], 0);
			tilesIndex++;
		}

		/*
		 * This section draws the single edge on the upper left part of the circle
		 */
		HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
		HexGridUtils.getUpperLeftSegmentVertices(tuples); // return array is [2][2]
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);

		/*
		 * This section draws the edges on the upper-right part of the circle
		 */
		HexGridUtils.getUpperRightRightSegmentVertices(tuples); // return array is [3][2]
		for (int i = 0; i < radius; i++) {
			HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[2][0], origin[1] + tuples[2][1], 0);
			tilesIndex++;
		}

		/*
		 * This section draws the single edge on the upper-right part of the circle
		 */
		HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
		HexGridUtils.getUpperRightSegmentVertices(tuples); // return array is [2][2]
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);

		/*
		 * This section draws the edges on the lower-right part of the circle
		 */
		HexGridUtils.getRightLowerRightSegmentVertices(tuples); // return array is [3][2]
		for (int i = 0; i < radius; i++) {
			HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[2][0], origin[1] + tuples[2][1], 0);
			tilesIndex++;
		}

		/*
		 * This section draws the single edge on the right part of the circle
		 */
		HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
		HexGridUtils.getRightSegmentVertices(tuples); // return array is [2][2]
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
		vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);

		/*
		 * This section draws the edges on the lower part of the circle
		 */
		HexGridUtils.getLowerRightLowerLeftSegmentVertices(tuples); // return array is [3][2]
		for (int i = 0; i < radius; i++) {
			HexGridUtils.getHexWorldOrigin(tiles[tilesIndex], origin);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[0][0], origin[1] + tuples[0][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[1][0], origin[1] + tuples[1][1], 0);
			vertices[verticesIndex++] = new Vector3(origin[0] + tuples[2][0], origin[1] + tuples[2][1], 0);
			tilesIndex++;
		}

		/*
		 * Draw the line.
		 */
		final Line line = new Line("ScannerCircleLine", vertices, null, null, null);
		line.updateModelBound();
		line.setLineWidth(1);
		line.setAntialiased(true);
		this.attachChild(line);

		/*
		 * The color of the circle is the same as the selected race color.
		 */
		final MaterialState renderState = new MaterialState();
		renderState.setAmbient(color);
		this.setRenderState(renderState);
	}

}
